package cn.jasonone.jfx.util;

import cn.jasonone.jfx.controls.Controller;
import cn.jasonone.jfx.mananger.ControllerManager;
import javafx.scene.Node;
import javafx.scene.Parent;
import javafx.scene.Scene;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.HashSet;
import java.util.Set;
import java.util.function.Predicate;
import java.util.stream.Collectors;

/**
 * @author xujie
 * @version 1.0
 * @date 2021/12/22 10:02
 */
@Component
public class NodeUtil {
    @Resource
    private ControllerManager controllerManager;

    /**
     * 获取节点的子节点信息
     *
     * @param node   节点对象
     * @param filter 过滤器
     * @return
     */
    public Set<Node> getChildNodes(Node node, Predicate<? super Node> filter) {
        Set<Node> nodes = node.lookupAll("*").stream().filter(filter).collect(Collectors.toSet());
        Set<Node> childNodes = new HashSet<>(nodes);
        for (Node n : nodes) {
            if (n != node) {
                childNodes.addAll(getChildNodes(n, filter));
            }
        }
        return childNodes.stream().filter(filter).collect(Collectors.toSet());
    }

    /**
     * 获取节点的子节点信息
     *
     * @param node 节点对象
     * @return
     */
    public Set<Node> getChildNodes(Node node) {
        return getChildNodes(node, n -> true);
    }

    /**
     * 获取节点中的所有控制器
     *
     * @param node
     * @return
     */
    public <C> Set<C> getControllers(Node node) {
        return (Set<C>) getControllers(node, c -> true);
    }

    /**
     * 获取场景中所有控制器
     *
     * @param scene
     * @param <C>
     * @return
     */
    public <C> Set<C> getControllers(Scene scene) {
        return controllerManager.getControllers(scene);
    }

    /**
     * 获取节点中的所有控制器
     *
     * @param node
     * @return
     */
    public <C> Set<C> getControllers(Node node, Predicate<Object> filter) {
        // 过滤非布局控件
        Set<Node> childNodes = getChildNodes(node, n -> n instanceof Parent || n instanceof Controller);
        return (Set<C>) childNodes.stream()
                // 获取布局控件的处理器
                .map(n -> controllerManager.getController((Parent) n))
                // 过滤空值
                .filter(n -> n != null)
                .filter(filter).collect(Collectors.toSet());
    }
}
